package carddeck;

import java.io.Serializable;

import GUI.gameWinOld.CardButton;

public class Card implements Serializable{
	private Suit cardSuit;
	private transient boolean highlighted;
	private transient boolean decoy;
	private transient CardButton button;
	private transient double scoreValue;

	public Suit getCardSuit() {
		return cardSuit;
	}

	public Rank getCardRank() {
		return cardRank;
	}

	public int getCardValue() {
		return cardValue;
	}

	public boolean isJoker() {
		return bJoker;
	}

	private Rank cardRank;
	private Card fakeCard;

	private int cardValue;
	private boolean bJoker;
	private boolean bAce;
	
	public Card() {
		System.out.println("using default constructor");
		decoy=true;
		cardSuit=null;
		cardRank=null;
		bJoker=false;
		fakeCard=null;
		cardValue=0;
	}
	
	public boolean isDecoy() {
		return decoy;
	}
	
	public boolean isAce() {
		return bAce;
	}
	
	public Card getFakeCard() {
		return fakeCard;
	}
	
	public Card getRealCard() {
		Card theCard = this;
		while(theCard.getFakeCard()!=null)
			theCard=theCard.getFakeCard();
		return theCard;
	}
	
	public Card(Suit cardSuit, Rank cardRank) {
		this.cardSuit = cardSuit;
		this.cardRank = cardRank;
		if(cardRank==null)
			throw new UnsupportedOperationException("Creating null rank fake card");
		if (cardRank == Rank.UNDEFINED)
			bJoker = true;
		else
			bJoker = false;
		if (cardRank == Rank.ACE)
			bAce = true;
		else
			bAce = false;
		fakeCard = null;
		cardValue = calculateValue();
	}

	private int calculateValue() {
		if (bJoker)
			return 100;
		else if (cardRank == Rank.ACE)
			return 20;
		else if (cardRank == Rank.JACK)
			return 30;
		else if (cardRank == Rank.FOUR)
			return 15;
		else if (cardRank == Rank.QUEEN)
			if (cardSuit == Suit.SPADES)
				return 75;
			else
				return 40;
		else if (cardRank == Rank.THREE)
			return 30;
		else if (cardRank == Rank.KING
				&& (cardSuit == Suit.HEARTS || cardSuit == Suit.SPADES))
			return 50;
		else if (cardRank == Rank.TWO)
			return 20;
		else
			return 5;
	}

	public boolean bIsNeutral() {
		if (bJoker
				|| cardRank == Rank.ACE
				|| cardRank == Rank.JACK
				|| cardRank == Rank.FOUR
				|| cardRank == Rank.QUEEN
				|| cardRank == Rank.THREE
				|| cardRank == Rank.TWO
				|| (cardRank == Rank.KING && (cardSuit == Suit.HEARTS || cardSuit == Suit.SPADES)))
			return false;
		else
			return true;
	}
	
	public boolean bIsDemandable() {
		return bIsNeutral()||cardRank==Rank.QUEEN;
	}
	
	public String cardToString() {
		if(bJoker)
			return "JKR";
		String str;
		if(cardRank==Rank.ACE)
			str="A";
		else if(cardRank==Rank.JACK)
			str="J";
		else if(cardRank==Rank.QUEEN)
			str="Q";
		else if(cardRank==Rank.KING)
			str="K";
		else if(cardRank==Rank.TEN)
			str="10";
		else
			str=""+cardRank.getValue();
		str+=" ";
		if(cardSuit==Suit.HEARTS)
			str+="KIER";
		else if(cardSuit==Suit.DIAMONDS)
			str+="KARO";
		else if(cardSuit==Suit.CLUBS)
			str+="TREFL";
		else 
			str+="PIK";
		return str;
	}

	public boolean isHighlighted() {
		return highlighted;
	}

	public void setHighlighted(boolean highlighted) {
		this.highlighted = highlighted;
	}

	public CardButton getButton() {
		return button;
	}

	public void setButton(CardButton button) {
		this.button = button;
	}
	public void setFakeCard(Card card) {
		if(!bJoker&&!bAce)
			return;
		fakeCard=card;
	}
	
	public boolean isOffensive() {
		Card realCard = getRealCard();
		if(realCard.getCardRank()==Rank.TWO||realCard.getCardRank()==Rank.THREE||realCard.getCardRank()==Rank.KING&&(realCard.getCardSuit()==Suit.HEARTS||realCard.getCardSuit()==Suit.SPADES))
			return true;
		return false;
	}
	
	public boolean isFour() {
		Card realCard = getRealCard();
		if(realCard.getCardRank()==Rank.FOUR)
			return true;
		return false;
	}
	
	public int getAttackValue() {
		if(!isOffensive())
			return 0;
		Card realCard = getRealCard();
		if(realCard.getCardRank()==Rank.TWO)
			return 2;
		if(realCard.getCardRank()==Rank.THREE)
			return 3;
		else
			return 5;
	}

	public double getScoreValue() {
		return scoreValue;
	}

	public void setScoreValue(double scoreValue) {
		this.scoreValue = scoreValue;
	}
	
	public boolean isEqualTo(Card other) {
		return cardRank==other.getCardRank()&&cardSuit==other.getCardSuit();
	}
	public boolean isEqualTo(Rank rank, Suit color) {
		return cardRank==rank&&cardSuit==color;
	}
}
